
#include    <stdio.h>
#include    <time.h>
#include    <unistd.h>
#include    <signal.h>

#include    "ev/ev++.h"

struct    MyTimer    :    public    ev::timer
{
public    :
    MyTimer(int iID) : m_iID(iID) {};
    
    int    id(void) const { return m_iID; };
    
private    :
    int    m_iID;
};

class Myclass
{

public    :
    Myclass (int fd)
        :    m_fd(fd)
    {
        m_io    .set <Myclass, &Myclass::io_cb  > (this);
        m_idle  .set <Myclass, &Myclass::idle_cb> (this);

        m_timer .set <Myclass, &Myclass::timer_cb> (this);
         
        m_mytimer = new MyTimer(1999);
        m_mytimer->set <Myclass, &Myclass::mytimer_cb> (this);

        m_signal.set <Myclass, &Myclass::signal_cb> (this);
        m_signal_30.set <Myclass, &Myclass::signal_cb> (this);
        m_signal_31.set <Myclass, &Myclass::signal_cb> (this);
        m_signal_int.set <Myclass, &Myclass::signal_cb> (this);
        m_signal_term.set <Myclass, &Myclass::signal_cb> (this);
        
        m_io.start (fd, ev::READ);
        //m_idle.start();
        
        m_timer.start(2.5, 1.5);

        m_mytimer->start(1, 1);
        
        m_signal.start(5);
        m_signal_30.start(30);
        m_signal_31.start(31);
        m_signal_int.start(SIGINT);
        m_signal_term.start(SIGTERM);
    }

private    :
    
    void     io_cb   (ev::io   &w, int revents)
    {
        m_io.stop();
        fprintf(stderr, "%s %s:%d %s(revents=0x%08X) ==== BEGIN ====\n", getTimeString(), __FILE__, __LINE__, __func__, revents);
        
        char    szBuf[1024];
        int    iReturn = read(m_fd, szBuf, sizeof(szBuf));
        szBuf[iReturn] = '\0';
        fprintf(stderr, "%s %s:%d %s() READ (fd=%d) '%s'\n", getTimeString(), __FILE__, __LINE__, __func__, m_fd, szBuf);
        
        fprintf(stderr, "%s %s:%d %s() ====  END  ====\n", getTimeString(), __FILE__, __LINE__, __func__);
        m_io.start(m_fd, ev::READ);
    }
    
    void     idle_cb (ev::idle &w, int revents)
    {
        fprintf(stderr, "%s %s:%d %s(revents=0x%08X) ==== BEGIN ====\n", getTimeString(), __FILE__, __LINE__, __func__, revents);
        fprintf(stderr, "%s %s:%d %s() ====  END  ====\n", getTimeString(), __FILE__, __LINE__, __func__);
    }
    
    void     timer_cb (ev::timer &w, int revents)
    {
        fprintf(stderr, "%s %s:%d %s(revents=0x%08X) ==== BEGIN ====\n", getTimeString(), __FILE__, __LINE__, __func__, revents);
        fprintf(stderr, "%s %s:%d %s() ====  END  ====\n", getTimeString(), __FILE__, __LINE__, __func__);
    }
    
    void     mytimer_cb (ev::timer &w, int revents)
    {
        MyTimer*    pTimer = static_cast<MyTimer *>(&w);
        
        fprintf(stderr, "%s %s:%d %s(revents=0x%08X) ==== BEGIN ====\n", getTimeString(), __FILE__, __LINE__, __func__, revents);
        fprintf(stderr, "%s %s:%d %s() ID=%d\n", getTimeString(), __FILE__, __LINE__, __func__, pTimer->id());
        fprintf(stderr, "%s %s:%d %s() ====  END  ====\n", getTimeString(), __FILE__, __LINE__, __func__);
    }
    
    void     signal_cb (ev::sig &w, int revents)
    {
        fprintf(stderr, "%s %s:%d %s(revents=0x%08X) ==== BEGIN ====\n", getTimeString(), __FILE__, __LINE__, __func__, revents);
        fprintf(stderr, "%s %s:%d %s() #%d signal got.\n", getTimeString(), __FILE__, __LINE__, __func__, w.signum);
        fprintf(stderr, "%s %s:%d %s() ====  END  ====\n", getTimeString(), __FILE__, __LINE__, __func__);
        
        if ( (2 == w.signum) || (15 == w.signum) ) {
            ev_unloop(m_loop, EVUNLOOP_ALL);
        }
    }

    static    const char*   getTimeString ( void )
    {
        #define    _BUF_SIZE    256
        static    char    s_szBuf[_BUF_SIZE];
        char    *pszBuf = s_szBuf;
        
        struct tm*  tmp;
        time_t  t;
        int     iReturn;
        
        pszBuf[0] = '\0';
        
        t = time (NULL);
        tmp = localtime( &t );
        if ( NULL == tmp ) {
            return  NULL;
        }
        
        pszBuf[0] = '\0';
        iReturn = strftime(pszBuf, _BUF_SIZE, "%Y-%m-%d %H:%M:%S", tmp);
        if (iReturn > 0) {
            pszBuf[ iReturn ] = '\0';
        }
        
        return  pszBuf;
    }   

public    :
    
    void    run(void)
    {
        m_loop = ev_default_loop(0);
        ev_loop(m_loop, 0);
    }
    
private    :
    int        m_fd;
    
    ev::io    m_io;  
    ev::idle  m_idle;  
    
    ev::timer  m_timer;
    
    MyTimer*   m_mytimer;
    
    ev::sig    m_signal, m_signal_30, m_signal_31, m_signal_int, m_signal_term;
    
    struct    ev_loop    *m_loop;
};


int    main(void)
{
    //struct ev_loop *loop = ev_default_loop (0);
    
    Myclass    myclass(/* FD: */0);
    
    //ev_loop (loop, 0);

    myclass.run();
    
    return    0;
}
